package com.dragon.hash;

import java.util.TreeMap;

/**
 * @author dragon
 * @version V1.0.0-RELEASE
 * @date 2019/5/27 17:16
 */
public class HashTable<K extends Comparable<K>, V> {

    private static final int upperTol = 10;
    private static final int lowerTol = 2;
    private static final int initCapacity = 7;
    private TreeMap<K, V>[] hashtable;
    private int M;
    private int size;

    public HashTable(int M) {
        this.M = M;
        hashtable = new TreeMap[M];
        for (int i = 0; i < hashtable.length; i++) {
            hashtable[i] = new TreeMap<>();
        }
    }

    public HashTable() {
        this(initCapacity);
    }

    /**
     * 哈希函数,将键 通过哈希函数 转换为 数组对应的 索引
     *
     * @param key
     * @return
     */
    private int hash(K key) {
        return (key.hashCode() & 0x7fffffff) % M;
    }

    public int size() {
        return size;
    }

    public void add(K key, V value) {
        TreeMap<K, V> treeMap = hashtable[hash(key)];
        if (treeMap.containsKey(key)) {
            treeMap.put(key, value);
        } else {
            treeMap.put(key, value);
            size++;
        }
    }

    public V remove(K key) {
        TreeMap<K, V> treeMap = hashtable[hash(key)];
        V returnValue = null;
        if (treeMap.containsKey(key)) {
            returnValue = treeMap.get(key);
            size--;
        }
        return returnValue;
    }

    public void set(K key, V value) {
        TreeMap<K, V> treeMap = hashtable[hash(key)];
        if (!treeMap.containsKey(key)) {
            throw new IllegalArgumentException("key 不存在");
        }
        treeMap.put(key, value);
    }

    public boolean contains(K key) {
        TreeMap<K, V> treeMap = hashtable[hash(key)];
        return treeMap.containsKey(key);
    }

    public V get(K key) {
        TreeMap<K, V> treeMap = hashtable[hash(key)];
        return treeMap.get(key);
    }
}
